﻿// 物资管理
import java.awt.*;
import java.sql.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class MaterialManagement {
	// 面板对象
	public static JPanel MaterialManagement = null;
	// 放置表格对象的面板，表格对象由于需要动态更新，所以默认里面是空的
	// 内容为物资编号，物资名称，单价, 数量
	public static JTable MaterialManagementTable = null;
	// 翻页标记，存储当前页码，默认为1，一页20条数据，翻页时改变此值
	// 翻页时先修改该值再执行updateData()函数更新数据
	public static int page = 1;
	// 页面显示标签，显示了当前页码和总页数
	public static JLabel pageLabel = null;


	// 更新数据函数，执行后会向数据库查询数据并更新本地数据
	public static void updateData()
	{
		System.out.println("正在更新物资管理数据...");
		try {
			Statement stmt = Main.conn.createStatement();// 创建语句对象
			// 获取表的长度
			ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM `HotelSysteam`.`Goods`");
			rs.next();// 移动到第一条数据
			int length = rs.getInt(1);// 获取长度
			// 如果长度为0，则不执行查询并将页码设置为NO DATA
			if(length == 0)
			{
				pageLabel.setText("NO DATA");
				System.out.println("没有数据，请添加数据后再进行查询。");
				return;
			}
			if(length % 20 != 0)// 如果长度不能被20整除，则总页数加1
			{
				length += 1;
			}
			int pageCount = length / 20 + (length % 20 == 0 ? 0 : 1);// 总页数
			if(page > pageCount)// 如果当前页码大于总页数，则设置为最后一页
			{
				page = pageCount;
			}
			rs.close();// 关闭结果集对象
			// 查询数据
			rs = stmt.executeQuery("SELECT * FROM `HotelSysteam`.`Goods` LIMIT " + ((page - 1) * 20) + ",20;");// 查询数据
			// 创建Object[][]
			Object[][] data = new Object[20][4];// 创建二维数组
			for(int i = 0;i < 20;i++)// 遍历二维数组
			{
				if(rs.next())// 如果还有数据，则继续执行
				{
					data[i][0] = rs.getString("ID");// 物资编号
					data[i][1] = rs.getString("Name");// 物资名称
					data[i][2] = rs.getDouble("Price");// 单价
					data[i][3] = rs.getInt("Quantity");// 数量
				}
				else// 如果没有数据，则跳出循环
				{
					break;
				}
			}
			rs.close();// 关闭结果集对象
			// 创建表格
			DefaultTableModel model = new DefaultTableModel(data, new String[] {"物资编号", "物资名称", "单价", "数量"});// 创建表格模型
			MaterialManagementTable.setModel(model);// 设置表格模型
			// 设置表格大小
			MaterialManagementTable.setPreferredScrollableViewportSize(new Dimension(300, 350));// 设置表格大小
			// 设置表格大小自适应
			MaterialManagementTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);// 设置表格大小自适应
			// 更新数据完毕，打印信息
			stmt.close();// 关闭语句对象
			// 设置页码
			pageLabel.setText(page + "/" + pageCount);

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static int findEmptyID()
	{
		try {
			Statement stmt = Main.conn.createStatement();// 创建语句对象
			int ID = -1;// 设置ID为-1，表示未找到空余ID
			// 循环查询数据库，直到找到空余ID为止 一次性查询50个ID，降低查询次数
			for(int i = 0;i <= 500;i++)// 查询500次作为上限，如果还没查到说明数据库已经满了
			{
				int IDMin = i * 50;// 计算最小ID
				// 如果是等于IDMin，则说明上一个循环因为达到了50个ID而跳出循环，那就继续查询下一组ID
				// 查询"SELECT ID FROM `HotelSysteam`.`Goods` ORDER BY `HotelSysteam`.`Goods`.ID ASC LIMIT " + IDMin + ",50";
				ResultSet rs = stmt.executeQuery("SELECT ID FROM `HotelSysteam`.`Goods` ORDER BY `HotelSysteam`.`Goods`.ID ASC LIMIT " + IDMin + ",50");// 查询数据库，获取ID列表，一次性查询50个ID
				// 遍历结果集
				while(rs.next())// 遍历结果集
				{
					IDMin = -1;// 重置IDMin为-1，表示该循环有过执行，用来过滤一些极端情况
					ID++;// ID加一
					// 获取当前ID的值
					int SID = rs.getInt("ID");// 获取当前ID的值

					if(SID == ID)// 如果ID相同，则继续查询下一个ID
					{
						continue;
					}
					else // 如果ID不同，则说明找到了空余ID，跳出循环
					{
						stmt.close();// 关闭语句对象
						rs.close();// 关闭结果集对象
						return ID;// 返回空余ID
					}
				}
				// 有一种极端情况，那就是项刚好是50的倍数，会导致上一个循环正常结束但下一个循环无法开始，所以需要提前拦截这种情况
				if(IDMin != -1)// 如果IDMin不为-1，则说明上一个循环正常结束但本循环无法开始
				{
					stmt.close();// 关闭语句对象
					rs.close();// 关闭结果集对象
					return ID+1;// 返回空余ID
				}
				// 如果ID小于IDMin
				// 则说明循环因为不足50个ID而跳出循环
				// 此时ID已经是循环的最后一个ID，也就是需要的空闲值
				IDMin = i * 50;
				if(ID < IDMin)// 如果ID小于IDMin，则跳出循环
				{
					return ID;// 返回空余ID
				}
			}
			System.err.println("数据库已满，无法找到空闲ID");
			stmt.close();// 关闭语句对象
			return -1;// 如果没有找到空余ID，则返回-1
		}
		catch (SQLException e) {
			System.err.println("数据库连接失败，无法查询空余ID");
			e.printStackTrace();
		}
		return -1;// 虽然理论上不会执行到这里，但还是加上以防万一
	}

	// 入库
	public static void inGoods()
	{
		System.err.println("正在执行入库操作...");
		// 弹窗,内含输入框，分别为物资编号，物资名称，单价，数量
		// 创建弹窗对象
		JDialog dialog = new JDialog();// 创建弹窗对象
		dialog.setTitle("入库 编号或名称检索，二选一");// 设置弹窗标题
		dialog.setSize(280, 200);// 设置弹窗大小
		dialog.setLocationRelativeTo(null);// 设置弹窗位置为屏幕中央
		dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);// 设置弹窗关闭方式为释放资源后关闭
		GridBagLayout grid = new GridBagLayout();// 定义布局对象
		dialog.setLayout(grid);// 设置布局对象
		JLabel label1 = new JLabel("编号:");// 创建标签对象
		GridBagConstraints c1 = new GridBagConstraints();// 定义布局对象
		c1.fill = GridBagConstraints.HORIZONTAL;// 设置填充方式为水平方向
		c1.gridx = 0;// 设置x坐标为0
		c1.gridy = 0;// 设置y坐标为0
		dialog.add(label1, c1);// 添加标签到弹窗中
		JTextField textField1 = new JTextField();// 创建文本框对象
		GridBagConstraints c2 = new GridBagConstraints();// 定义布局对象
		c2.fill = GridBagConstraints.HORIZONTAL;// 设置填充方式为水平方向
		c2.gridx = 1;// 设置x坐标为1
		c2.gridy = 0;// 设置y坐标为0
		c2.gridwidth = 3;// 横向占用3个格子
		dialog.add(textField1, c2);// 添加文本框到弹窗中
		JLabel label2 = new JLabel("名称:");// 创建标签对象
		GridBagConstraints c3 = new GridBagConstraints();// 定义布局对象
		c3.fill = GridBagConstraints.HORIZONTAL;// 设置填充方式为水平方向
		c3.gridx = 0;// 设置x坐标为0
		c3.gridy = 1;// 设置y坐标为1
		dialog.add(label2, c3);// 添加标签到弹窗中
		JTextField textField2 = new JTextField();// 创建文本框对象
		GridBagConstraints c4 = new GridBagConstraints();// 定义布局对象
		c4.fill = GridBagConstraints.HORIZONTAL;// 设置填充方式为水平方向
		c4.gridx = 1;// 设置x坐标为1
		c4.gridy = 1;// 设置y坐标为1
		c4.gridwidth = 3;// 横向占用3个格子
		dialog.add(textField2, c4);// 添加文本框到弹窗中
		JLabel label4 = new JLabel("数量:");// 创建标签对象
		GridBagConstraints c7 = new GridBagConstraints();// 定义布局对象
		c7.fill = GridBagConstraints.HORIZONTAL;// 设置填充方式为水平方向
		c7.gridx = 0;// 设置x坐标为0
		c7.gridy = 2;// 设置y坐标为3
		dialog.add(label4, c7);// 添加标签到弹窗中
		JTextField textField4 = new JTextField();// 创建文本框对象
		GridBagConstraints c8 = new GridBagConstraints();// 定义布局对象
		c8.fill = GridBagConstraints.HORIZONTAL;// 设置填充方式为水平方向
		c8.gridx = 1;// 设置x坐标为1
		c8.gridy = 2;// 设置y坐标为3
		c8.gridwidth = 3;// 横向占用3个格子
		dialog.add(textField4, c8);// 添加文本框到弹窗中
		JButton button1 = new JButton("确定");// 创建按钮对象
		GridBagConstraints c9 = new GridBagConstraints();// 定义布局对象
		c9.fill = GridBagConstraints.HORIZONTAL;// 设置填充方式为水平方向
		c9.gridx = 0;// 设置x坐标为0
		c9.gridy = 3;// 设置y坐标为4
		c9.gridwidth = 2;// 横向占用2个格子
		dialog.add(button1, c9);// 添加按钮到弹窗中
		JButton button2 = new JButton("取消");// 创建按钮对象
		GridBagConstraints c10 = new GridBagConstraints();// 定义布局对象
		c10.fill = GridBagConstraints.HORIZONTAL;// 设置填充方式为水平方向
		c10.gridx = 2;// 设置x坐标为2
		c10.gridy = 3;// 设置y坐标为4
		c10.gridwidth = 2;// 横向占用2个格子
		dialog.add(button2, c10);// 添加按钮到弹窗中	
		dialog.setVisible(true);// 显示对话框
		// 设置按钮事件
		button1.addActionListener(e1 -> {
			System.out.println("正在执行入库操作...");
			String IID = textField1.getText();// 获取文本框内容
			String IName = textField2.getText();// 获取文本框内容
			String ICount = textField4.getText();// 获取文本框内容
			// 检查id是否为空，如果为空则用名称代替搜索，重名则提示错误
			// 如果有ID则直接用ID搜索，毕竟ID是唯一的，不可能重名
			if (IID.isEmpty())// 如果ID为空，则用名称代替搜索
			{
				if (IName.isEmpty())// 如果名称也为空，则提示错误
				{
					System.err.println("编号或名称不能为空");
					return;
				}
				else// 如果有名称，则用名称代替搜索
				{
					System.out.println("编号为空，正在用名称代替搜索...");
					// 用名称查ID
					try {
						String sql = "SELECT * FROM HotelSysteam.Goods WHERE Name = '" + IName + "'";// 定义SQL语句
						Statement stmt = Main.conn.createStatement();// 创建语句对象
						ResultSet rs = stmt.executeQuery(sql);// 执行查询操作
						if (rs.next())// 如果查询到数据，则获取ID并赋值给IID变量
						{
							IID = rs.getString("ID");// 获取ID并赋值给IID变量
						}
						else// 如果没有查询到数据，则提示错误
						{
							System.err.println("未找到该物资信息");
							return;
						}
						rs.close();// 关闭结果集
						stmt.close();// 关闭语句对象
					} catch (SQLException e) {
						System.err.println("通过名称查询物资发生错误");
						e.printStackTrace();
					}
				}
			}
			// ID已获取，接下来执行入库操作
			try {// 执行入库操作
				Statement stmt = Main.conn.createStatement();// 创建语句对象
				// 查询当前ID的存量
				ResultSet rs = stmt.executeQuery("SELECT * FROM HotelSysteam.Goods WHERE ID = " + IID);// 执行查询操作
				if (rs.next())// 如果查询到数据，则获取存量并赋值给变量
				{
					int stock = rs.getInt("Quantity");// 获取存量并赋值给变量
					stock += Integer.parseInt(ICount);// 将入库数量加到存量上
					System.out.println("存量已更新为：" + stock);
					// 更新存量
					stmt.executeUpdate("UPDATE HotelSysteam.Goods SET Quantity = " + stock + " WHERE ID = " + IID);// 执行更新操作

				}
				else// 如果没有查询到数据，则提示错误
				{
					System.err.println("未找到该物资信息");
				}
				rs.close();// 关闭结果集
				stmt.close();// 关闭语句对象
			} catch (NumberFormatException e) {
				System.err.println("入库数量不是数字，请检查输入");
				// 弹窗提示入库数量不是数字，请检查输入
				JOptionPane.showMessageDialog(null, "入库数量不是数字，请检查输入", "错误", JOptionPane.ERROR_MESSAGE);
				e.printStackTrace();
			} catch (SQLException e) {
				System.err.println("入库发生错误，也许ID不存在，请检查ID是否正确");
				e.printStackTrace();
			}
			dialog.dispose();// 关闭对话框
			updateData();// 更新数据

		});// 添加按钮事件
		button2.addActionListener(e2 -> {
			System.out.println("已取消入库操作");
			dialog.dispose();// 关闭对话框
		});// 添加按钮事件
	}
	// 出库
	public static void outGoods()
	{
		System.err.println("正在执行出库操作...");
		// 和入库的逻辑差不多，只不过入库是加存量，出库是减存量
		JDialog dialog = new JDialog();// 创建对话框对象
		dialog.setTitle("出库");// 设置标题为"出库"
		dialog.setSize(280, 200);// 设置大小
		GridBagLayout grid1 = new GridBagLayout();// 定义布局对象
		dialog.setLayout(grid1);// 设置布局为网格布局
		JLabel label1 = new JLabel("编号:");// 标签对象，内容为"编号:"
		GridBagConstraints c1 = new GridBagConstraints();// 定义约束
		c1.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c1.gridx = 0;// 横向位置为0
		c1.gridy = 0;// 纵向位置为0
		dialog.add(label1, c1);// 添加到面板
		JTextField textField1 = new JTextField();// 文本框对象
		GridBagConstraints c2 = new GridBagConstraints();// 定义约束
		c2.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c2.gridx = 1;// 横向位置为1
		c2.gridy = 0;// 纵向位置为0
		c2.gridwidth = 3;// 宽度为3
		dialog.add(textField1, c2);// 添加到面板
		JLabel label2 = new JLabel("名称:");// 标签对象，内容为"名称:"
		GridBagConstraints c3 = new GridBagConstraints();// 定义约束
		c3.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c3.gridx = 0;// 横向位置为0
		c3.gridy = 1;// 纵向位置为1
		dialog.add(label2, c3);// 添加到面板
		JTextField textField2 = new JTextField();// 文本框对象
		GridBagConstraints c4 = new GridBagConstraints();// 定义约束
		c4.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c4.gridx = 1;// 横向位置为1
		c4.gridy = 1;// 纵向位置为1
		c4.gridwidth = 3;// 宽度为3
		dialog.add(textField2, c4);// 添加到面板
		JLabel label3 = new JLabel("数量:");// 标签对象，内容为"数量:"
		GridBagConstraints c5 = new GridBagConstraints();// 定义约束
		c5.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c5.gridx = 0;// 横向位置为0
		c5.gridy = 2;// 纵向位置为2
		dialog.add(label3, c5);// 添加到面板
		JTextField textField4 = new JTextField();// 文本框对象
		GridBagConstraints c6 = new GridBagConstraints();// 定义约束
		c6.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c6.gridx = 1;// 横向位置为1
		c6.gridy = 2;// 纵向位置为2
		c6.gridwidth = 3;// 宽度为3
		dialog.add(textField4, c6);// 添加到面板
		JButton button1 = new JButton("确定");// 按钮对象，内容为"确定"
		GridBagConstraints c7 = new GridBagConstraints();// 定义约束
		c7.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c7.gridx = 0;// 横向位置为0
		c7.gridy = 3;// 纵向位置为3
		c7.gridwidth = 2;// 宽度为2
		dialog.add(button1, c7);// 添加到面板
		JButton button2 = new JButton("取消");// 按钮对象，内容为"取消"
		GridBagConstraints c8 = new GridBagConstraints();// 定义约束
		c8.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c8.gridx = 2;// 横向位置为2
		c8.gridy = 3;// 纵向位置为3
		c8.gridwidth = 2;// 宽度为2
		dialog.add(button2, c8);// 添加到面板
		dialog.setLocationRelativeTo(null);// 设置对话框居中显示
		dialog.setVisible(true);// 设置为可见状态
		button1.addActionListener(e -> {// 添加按钮事件
			String IID = textField1.getText();// 获取文本框内容
			String IName = textField2.getText();// 获取文本框内容
			String ICount = textField4.getText();// 获取文本框内容
			System.out.println("正在执行出库操作...");
			// 检查id是否为空，如果为空则用名称代替搜索，重名则提示错误
			// 如果有ID则直接用ID搜索，毕竟ID是唯一的，不可能重名
			if (IID.isEmpty())// 如果ID为空，则用名称代替搜索
			{
				if (IName.isEmpty())// 如果名称也为空，则提示错误
				{
					System.err.println("编号或名称不能为空");
					return;
				}
				else// 如果有名称，则用名称代替搜索
				{
					System.out.println("编号为空，正在用名称代替搜索...");
					// 用名称查ID
					try {
						String sql = "SELECT * FROM HotelSysteam.Goods WHERE Name = '" + IName + "'";// 定义SQL语句
						Statement stmt = Main.conn.createStatement();// 创建语句对象
						ResultSet rs = stmt.executeQuery(sql);// 执行查询操作
						if (rs.next())// 如果查询到数据，则获取ID并赋值给IID变量
						{
							IID = rs.getString("ID");// 获取ID并赋值给IID变量
						}
						else// 如果没有查询到数据，则提示错误
						{
							System.err.println("未找到该物资信息");
							return;
						}
						rs.close();// 关闭结果集
						stmt.close();// 关闭语句对象
					} catch (SQLException e1) {
						System.err.println("通过名称查询物资发生错误");
						e1.printStackTrace();
					}
				}
			}
			// ID已获取，接下来执行入库操作
			try {// 执行入库操作
				Statement stmt = Main.conn.createStatement();// 创建语句对象
				// 查询当前ID的存量
				ResultSet rs = stmt.executeQuery("SELECT * FROM HotelSysteam.Goods WHERE ID = " + IID);// 执行查询操作
				if (rs.next())// 如果查询到数据，则获取存量并赋值给变量
				{
					int stock = rs.getInt("Quantity");// 获取存量并赋值给变量
					stock -= Integer.parseInt(ICount);// 将入库数量减去存量
					if (stock < 0)// 如果存量小于0，则弹窗提示并终止操作
					{
						System.err.println("存量不足，无法出库");
						JOptionPane.showMessageDialog(null, "存量不足，无法出库", "错误", JOptionPane.ERROR_MESSAGE);
						rs.close();// 关闭结果集
						stmt.close();// 关闭语句对象
						return;
					}

					System.out.println("存量已更新为：" + stock);
					// 更新存量
					stmt.executeUpdate("UPDATE HotelSysteam.Goods SET Quantity = " + stock + " WHERE ID = " + IID);// 执行更新操作

				}
				else// 如果没有查询到数据，则提示错误
				{
					System.err.println("未找到该物资信息");
				}
				rs.close();// 关闭结果集
				stmt.close();// 关闭语句对象
			} catch (NumberFormatException e1) {
				System.err.println("出库数量不是数字，请检查输入");
				// 弹窗提示入库数量不是数字，请检查输入
				JOptionPane.showMessageDialog(null, "入库数量不是数字，请检查输入", "错误", JOptionPane.ERROR_MESSAGE);
				e1.printStackTrace();
			} catch (SQLException e1) {
				System.err.println("出库发生错误，也许ID不存在，请检查ID是否正确");
				e1.printStackTrace();
			}
			dialog.dispose();// 关闭对话框
			updateData();// 更新数据
		}); // 添加按钮事件
		button2.addActionListener(e -> {// 添加按钮事件
			System.out.println("已取消出库操作");// 打印日志
			dialog.dispose();// 关闭对话框
		}); // 添加按钮事件 
	}
	// 新增物资信息
	public static void addGoods()
	{
		System.out.println("正在执行新增物资信息操作...");
		JDialog dialog = new JDialog();// 创建对话框对象
		dialog.setTitle("新增物资信息");// 设置标题为"新增物资信息"
		dialog.setSize(280, 200);// 设置对话框大小
		GridBagLayout grid = new GridBagLayout();// 定义布局对象
		dialog.setLayout(grid);// 布局
		JLabel label1 = new JLabel("编号:");// 标签对象，内容为"编号:"
		GridBagConstraints c1 = new GridBagConstraints();// 定义约束
		c1.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c1.gridx = 0;// 横向位置为0
		c1.gridy = 0;// 纵向位置为0
		dialog.add(label1, c1);// 添加到面板
		JTextField textField1 = new JTextField();// 文本框对象
		GridBagConstraints c2 = new GridBagConstraints();// 定义约束
		c2.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c2.gridx = 1;// 横向位置为1
		c2.gridy = 0;// 纵向位置为0
		textField1.setText(""+findEmptyID());// 设置文本框内容为空ID
		dialog.add(textField1, c2);// 添加到面板
		JLabel label2 = new JLabel("名称:");// 标签对象，内容为"名称:"
		GridBagConstraints c3 = new GridBagConstraints();// 定义约束
		c3.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c3.gridx = 0;// 横向位置为0
		c3.gridy = 1;// 纵向位置为1
		dialog.add(label2, c3);// 添加到面板
		JTextField textField2 = new JTextField();// 文本框对象
		GridBagConstraints c4 = new GridBagConstraints();// 定义约束
		c4.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c4.gridx = 1;// 横向位置为1
		c4.gridy = 1;// 纵向位置为1
		textField2.setText("");// 设置文本框内容为空
		dialog.add(textField2, c4);// 添加到面板
		JLabel label3 = new JLabel("单价:");// 标签对象，内容为"单价:"
		GridBagConstraints c5 = new GridBagConstraints();// 定义约束
		c5.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c5.gridx = 0;// 横向位置为0
		c5.gridy = 2;// 纵向位置为2
		dialog.add(label3, c5);// 添加到面板
		JTextField textField3 = new JTextField();// 文本框对象
		GridBagConstraints c6 = new GridBagConstraints();// 定义约束
		c6.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c6.gridx = 1;// 横向位置为1
		c6.gridy = 2;// 纵向位置为2
		textField3.setText("");// 设置文本框内容为空
		dialog.add(textField3, c6);// 添加到面板
		JButton button1 = new JButton("确定");// 按钮对象，内容为"确定"
		JButton button2 = new JButton("取消");// 按钮对象，内容为"取消"
		GridBagConstraints c7 = new GridBagConstraints();// 定义约束
		c7.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c7.gridx = 0;// 横向位置为0
		c7.gridy = 3;// 纵向位置为3
		dialog.add(button1, c7);// 添加到面板
		GridBagConstraints c8 = new GridBagConstraints();// 定义约束
		c8.fill = GridBagConstraints.HORIZONTAL;// 填充方式为水平方向
		c8.gridx = 1;// 横向位置为1
		c8.gridy = 3;// 纵向位置为3
		dialog.add(button2, c8);// 添加到面板
		// 执行按钮点击事件
		button1.addActionListener(e -> {
			System.out.println("正在执行新增物资信息操作...");
			String ID = textField1.getText();// 获取文本框内容
			String Name = textField2.getText();// 获取文本框内容
			String Price = textField3.getText();// 获取文本框内容
			// 编号为空则提示错误并返回
			if (ID.isEmpty())// 编号为空则提示错误并返回
			{
				System.err.println("编号不能为空");
				JOptionPane.showMessageDialog(null, "编号不能为空", "错误", JOptionPane.ERROR_MESSAGE);
				return;
			}
			// 名称为空则提示错误并返回
			if (Name.isEmpty())// 名称为空则提示错误并返回
			{
				System.err.println("名称不能为空");
				JOptionPane.showMessageDialog(null, "名称不能为空", "错误", JOptionPane.ERROR_MESSAGE);
				return;
			}
			// 单价为空则默认赋值为0
			if (Price.isEmpty())// 单价为空则默认赋值为0
			{
				System.out.println("单价为空，已默认为0");
				Price = "0";
			}
			// 检查ID和单价是否为数字，如果不是则提示错误并返回
			try {
				Integer.parseInt(ID);// 检查编号是否为数字
				Double.parseDouble(Price);// 检查单价是否为数字
			} catch (NumberFormatException e1) {
				System.err.println("编号或单价不是数字，请检查输入");
				JOptionPane.showMessageDialog(null, "编号或单价不是数字，请检查输入", "错误", JOptionPane.ERROR_MESSAGE);
				return;
			}
			// 查找是否服务器中是否存在该ID
			try {
				Statement stmt = Main.conn.createStatement();// 创建语句对象
				ResultSet rs = stmt.executeQuery("SELECT * FROM HotelSysteam.Goods WHERE ID = " + ID);// 执行查询操作
				if (rs.next())// 如果查询到数据，则提示并询问是否覆盖，弹窗包含原始和新的数据方便对照
				{
					System.out.println("已找到该物资信息，是否覆盖？");// 打印日志
					int xz = JOptionPane.showConfirmDialog(null,
					"已找到该物资信息，是否覆盖？\n原始数据：ID=" + rs.getString("ID") + 
					", 名称="+ rs.getString("Name") + 
					", 单价=" + rs.getString("Price") +  
					"\n替换数据：ID=" + ID + 
					", 名称=" + Name + 
					", 单价=" + Price, "提示", JOptionPane.YES_NO_OPTION);
					if (xz == 0)// 如果用户选择是，则继续执行添加操作
					{
						stmt.executeUpdate("UPDATE HotelSysteam.Goods SET Name = '" + Name + "', Price = " + Price + " WHERE ID = " + ID);
						System.out.println("更新物资信息成功！");
					}
					else// 如果用户选择否，则不执行任何操作
					{
						System.out.println("已取消新增物资信息操作");
					}
				}
				else// 如果没有查询到数据，则继续执行添加操作
				{
					stmt.executeUpdate("INSERT INTO HotelSysteam.Goods VALUES (" + ID + ", '" + Name + "', " + Price + ", 0)");
					System.out.println("新增物资信息成功！");
				}
				rs.close();// 关闭结果集
				stmt.close();// 关闭语句对象
			} catch (SQLException e1) {
				System.err.println("新增物资信息失败\n数据库连接失败");
				JOptionPane.showMessageDialog(null, "新增物资信息失败\n数据库连接失败", "错误", JOptionPane.ERROR_MESSAGE);
				e1.printStackTrace();
			} catch (Exception e1) {
				System.err.println("新增物资信息失败\n未知的错误来源");
				JOptionPane.showMessageDialog(null, "新增物资信息失败\n未知的错误来源", "错误", JOptionPane.ERROR_MESSAGE);

				e1.printStackTrace();
			}

			dialog.dispose();// 关闭对话框
			updateData();// 更新数据
		}); // 添加按钮事件
		button2.addActionListener(e -> {
			System.out.println("已取消新增物资信息操作");
			dialog.dispose();// 关闭对话框
		}); // 添加按钮事件
		// 显示对话框
		dialog.setLocationRelativeTo(null);// 居中显示
		dialog.setVisible(true);// 显示对话框
	}

	// 翻页函数，执行后会改变当前页码并更新数据
	public static void changePage()
	{
		System.out.println("正在切换物资管理页面...");
		page += 1;// 页码加一
		updateData();// 更新数据
	}
	// 上一页函数，执行后会改变当前页码并更新数据
	public static void lastPage()
	{
		System.out.println("正在切换物资管理页面...");
		if(page > 1)// 如果不是第一页，则页码减一
		{
			page -= 1;
		}
		else// 如果是第一页，则不执行任何操作
		{
			return;
		}
		updateData();// 更新数据
	}

	// 初始化面板函数，执行后会创建面板并添加控件
	public static void init()
	{
		System.out.println("正在初始化物资管理...");
		// 定义ui控件
		MaterialManagement = new JPanel();// 物资管理面板
		GridBagLayout grid1 = new GridBagLayout();// 定义布局对象
		MaterialManagement.setLayout(grid1);// 布局

		JLabel label1 = new JLabel("物资管理");// 标签对象
		// 宽度三，高度一，位于第一行
		GridBagConstraints c1 = new GridBagConstraints();// 定义约束
		c1.gridx = 0;// 横向位置
		c1.gridy = 0;// 纵向位置
		c1.gridwidth = 3;// 宽度
		c1.gridheight = 1;// 高度
		MaterialManagement.add(label1, c1);// 添加到面板
		// 三个按钮对象，分别为入库，出库，报损
		JButton button1 = new JButton("入库");// 入库按钮
		GridBagConstraints c2 = new GridBagConstraints();// 定义约束
		c2.fill = GridBagConstraints.HORIZONTAL;// 填充方式
		c2.gridx = 0;// 横向位置
		c2.gridy = 1;// 纵向位置
		// 执行按钮点击事件
		button1.addActionListener(e -> {
			inGoods();
		});
		button1.setPreferredSize(new Dimension(100, 30));// 设置按钮大小
		MaterialManagement.add(button1, c2);// 添加到面板
		JButton button2 = new JButton("出库");// 出库按钮
		GridBagConstraints c3 = new GridBagConstraints();// 定义约束
		c3.fill = GridBagConstraints.HORIZONTAL;// 填充方式
		c3.gridx = 1;// 横向位置
		c3.gridy = 1;// 纵向位置
		button2.addActionListener(e -> {
			outGoods();
		});
		button2.setPreferredSize(new Dimension(100, 30));// 设置按钮大小
		MaterialManagement.add(button2, c3);// 添加到面板
		JButton button3 = new JButton("新增/更改");// 报损按钮
		GridBagConstraints c4 = new GridBagConstraints();// 定义约束
		c4.fill = GridBagConstraints.HORIZONTAL;// 填充方式
		c4.gridx = 2;// 横向位置
		c4.gridy = 1;// 纵向位置
		button3.addActionListener(e -> {
			addGoods();
		});
		button3.setPreferredSize(new Dimension(100, 30));// 设置按钮大小
		MaterialManagement.add(button3, c4);// 添加到面板
		// 表格对象，默认里面是空的
		MaterialManagementTable = new JTable();// 表格对象
		GridBagConstraints c5 = new GridBagConstraints();// 定义约束
		c5.fill = GridBagConstraints.HORIZONTAL;// 填充方式
		c5.gridx = 0;// 横向位置
		c5.gridy = 2;// 纵向位置
		c5.gridwidth = 3;// 宽度
		c5.gridheight = 10;// 高度
		MaterialManagement.add(new JScrollPane(MaterialManagementTable), c5);// 添加到面板
		// 翻页按钮和页面显示标签
		JButton button4 = new JButton("上一页");// 翻页按钮
		GridBagConstraints c6 = new GridBagConstraints();// 定义约束
		c6.fill = GridBagConstraints.HORIZONTAL;// 填充方式
		c6.gridx = 0;// 横向位置
		c6.gridy = 12;// 纵向位置
		button4.setPreferredSize(new Dimension(100, 30));// 设置按钮大小
		MaterialManagement.add(button4, c6);// 添加到面板
		pageLabel = new JLabel("ERROR");// 页面显示标签
		GridBagConstraints c7 = new GridBagConstraints();// 定义约束
		c7.fill = GridBagConstraints.HORIZONTAL;// 填充方式
		c7.gridx = 1;// 横向位置
		c7.gridy = 12;// 纵向位置
		pageLabel.setPreferredSize(new Dimension(100, 30));// 设置按钮大小
		MaterialManagement.add(pageLabel, c7);// 添加到面板
		JButton button5 = new JButton("下一页");// 翻页按钮
		GridBagConstraints c8 = new GridBagConstraints();// 定义约束
		c8.fill = GridBagConstraints.HORIZONTAL;// 填充方式
		c8.gridx = 2;// 横向位置
		c8.gridy = 12;// 纵向位置
		button5.setPreferredSize(new Dimension(100, 30));// 设置按钮大小
		MaterialManagement.add(button5, c8);// 添加到面板
		// 更新数据
		updateData();// 更新数据
	}	
}
